Double-Caesar Cipher

Table of Contents

This assignment is to be done individually. You can talk to other people in the class, me (Dave), the prefect, and lab assistants for ideas and to gain assistance. You can help each other debug programs, if you wish. The code that you write should be your own, however, and you shouldn’t hand a printout of your program to others. See the course syllabus for more details or just ask me if I can clarify.

1. Overview

An important class of algorithms that some computer scientists concern themselves with are encryption and decryption techniques. How can text be encoded so that no one can read it apart from the desired recipient? This is critical for trade secrets and government messages, but even more critical for such common needs as secure web-based purchases, being able to send your password over the web without others listening in, and so on.

An old simplistic trick is the Caesar cipher. Pick a key from 1 to 25; then for each character in your message, shift each letter forward by the key, wrapping around the end of the alphabet. For example, if your original message is helloyou, and your key is 2, your encrypted message is jgnnqaqw. Supposedly, Julius Caesar used this technique to communicate with his generals. It is very easy to crack, however.

A slightly harder but dramatically more effective variation is the double-Caesar cipher. It works just like the Caesar cipher, but each letter in your message gets shifted by a different amount. How much? It is based on another string of text, called the key. Each letter in the key tells you how many letters to advance: an a is 0, a b is 1, and so on. For example, if your original message is helloyou and your key is dog, the d in dog means that you shift the first letter of helloyou 3 letters, the o in dog means you shift the second letter of helloyou by 14 letters, and the g in dog means you shift the third letter of helloyou by 6 letters. You then repeat the pattern: the fourth letter of helloyou gets shifted by 3 letters, the fifth letter gets shifted by 14 letters, and so on. This produces the encrypted message ksroceri. Double-Caesar ciphers are actually quite hard to crack.

Just to try to help make it clear, here’s that same encoding again:

Original:     h e l l o y o u
Repeated key: d o g d o g d o
Encrypted:    k s r o c e r i

2. Get started

Create a folder in which to store your work for this assignment.

  • If you are working on your own computer, it’s up to you where to put the folder. Your desktop is likely as good a place as any. Make a folder titled cipher.
  • If you are working in the labs in Olin, make sure to first mount the COURSES folder, so that you won’t lose your code when you log out. Once you’ve done so, open up Finder, then navigate to your personal student work folder. You can then make a cipher folder within there.
  • Once you’ve done so, you should then open up your new folder in VS Code. To do so, start up VS Code, then drag your folder onto the VS Code window. This should open up the folder within VS Code. If you are asked, click that you trust the authors.

3. Your assignment

You will actually write two programs.

3.1. The first program

The first program, called encoder.py, should have the user first enter in a message in English, and then a key. Your program should assume that your input text is entirely in lower case, with no punctuation, and no spaces. encoder.py should read in this information, then print out to the screen the encrypted message via the double-Caesar cipher.

Here is a sample run below.

What is the original message? helloyou
What is the key? dog
The encrypted message is ksroceri

Once you have the basic input setup working, you should save yourself time by putting your input in a file, and redirecting your input from there. That is how we will test your code. In other words, we will create a file that looks like this:

helloyou
dog

Redirecting your input from a file differs depending on whether you’re using a Mac or Windows. On a Mac, if that input file happened to be named source.txt, we would run your program as follows:

python3 encoder.py < source.txt

Alternatively, on Windows, if you are running in the Windows PowerShell prompt (this should be the default in VSCode), the following should work:

cat source.txt | python3 encoder.py

(As it turns out, this Windows PowerShell approach also works on Macs.)

3.2. The second program

Your second program, called decoder.py, should read an encrypted message and a key. Your program should assume that your encrypted text is entirely in lower case, with no punctuation, and no spaces. Similarly to the above, your program should first prompt for the encrypted message, and then prompt for the key. Your program should print out the decoded message to the screen.

Here is a sample run below.

What is the encrypted message? ksroceri
What is the key? dog
The original message is helloyou

As with the first program, you’ll be faster at testing it (and we will test it this way) by redirecting from an input file. See instructions above on how to do this.

4. Some Python notes and hints

Some of you may be tempted to write an if statement with 26 cases, one for each letter of the alphabet. Do not do this; make use of the built-in chr and ord functions, which help you convert letters to numbers and back again. Try the following program to see what you get:

print(ord("a"))
print(chr(98))
Here are some further hints, that I only recommend looking at if you're stuck. You might enjoy more figuring this out for yourself. (Click the triangle to the left to unhide)

It might seem confusing regarding what to loop over. Do you loop over the message, or over the key? Or both? This assignment is dramatically easier to do if you set up your loop so that the loop variable is a number, representing the position in the string. Here’s an example:

message = "helloyou"
for i in range(len(message)):
    print(message[i])

You can then similarly get the corresponding location in the key via something like this:

message = "helloyou"
key = "dog"
for i in range(len(message)):
    print(message[i])
    print(key[i])

The problem is that if the message is longer than they key, you’ll need to wrap back around to the beginning of the key. This is another fantastic place to use the remainder operation %.

5. Exemplary grade

If you get this far, you should feel proud of your achievements! If you want to push yourself harder and go for the exemplary grade, do the following extra challenge.

Submit a variation on your programs that allows the user to vary the size of the alphabet, and uses fewer or more letters as necessary. For example, if the size of the alphabet is 5, then it only has the letters a, b, c, d, and e. On the other hand, if the size of the alphabet is 29, then it goes beyond z to the characters in the ASCII table that go past it. (We won’t test an alphabet size greater than 30).

Here is what a sample run would look like:

What is the original message? aceab
What is the key? bcb
What is the alphabet size? 5
The encrypted message is beabd

You should do the above with no if statements in your code.

If you do this, first do the original approach as described above, then submit your updated programs as encoder_variable.py and decoder_variable.py. Separating this out makes grading easier.

6. Style

You should make sure that your program follows good style. You should it as readable as possible for someone else trying to understand them. At a minimum, you should put a comment at the top explaining what the program does, and use comments above consecutive portions of Python code explaining what they do. You should also use meaningful and readable variable names. Furthermore, your code should be minimal where reasonable. In other words, your code shouldn’t contain an excessive number of variables or lines of code, unless doing so adds to readability.

Your code should contain no if statements. We will eventually use lots of if statements, but I want you to get practice doing this in a more direct way by doing the correct arithmetic.

7. Grading

You will receive an M for this assignment if…

  • your program displays the right output for test cases that we try. Specifically, here are the cases you need to get correct, both encoding and decoding:
original key encoded
helloyou dog ksroceri
amazingelephant gadzooks gmdywbqwresgobd
what verylong rlrr
  • your program is written to work in general, and not to only work for the specific tests that we have provided.
  • you don’t use any if statements.
  • the 26 letters of the alphabet don’t explicitly appear in your code in some fashion. As an example, you don’t have code that looks something like

      if letter=='a' or letter=='b' or ...
    

You will receive a grade of E for this assignment if you satisfy the above M requirements, and …

  • your program has a comment at the top with at least 5 words describing what the program does.
  • every one of your variable names is meaningful in some way. (Names such as thing, number, etc. are not meaningful.)
  • You have at least one other comment near what you think is the trickiest part of your code, describing how it works
  • your code demonstrates a clear sequence of actions to achieve the goal at hand, and each piece is essential. Your code does not have notably more cases or conditions than it needs to.
  • you have achieved the E goal described above. Here are the test cases you must get correct:
original key size encoded
hellofriend dog 20 ksroilackqr
amazinghappyelephant gadzoovth 29 gmdvw||{hvp|azsh{htt
hahaha cab 10 jaichb

8. Submit your work

When finished, zip up your code and submit your work through Moodle.

Good luck, and have fun! Remember that lab assistants are available to help out if you need it, and you can attend prefect sessions as well.

Author: Dave Musicant